package plugins.jTreeFolder;



import interfaces.TreeInterface;

import java.io.*;

import java.awt.*;

import javax.swing.*;

import javax.swing.event.*;

import javax.swing.tree.*;

import annotation.Menu;



/**
 * 
 * @param seeFile true pour afficher les fichiers false pour ne pas les affichés et donc voir que les dossiers
 * @author Amine HALLILI amine.hallili@gmail.com
 */
public class JTreeFolder implements TreeInterface,Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	protected NodeWithFile racine;
    private JTree tree;
    final boolean seeFile=false;// permet d'afficher ou masquer les fichier
    protected JScrollPane scrollpane;
    private TreeSelectionEvent ev;
    boolean parDefaut =true;
    private File savingFile= new File("tree.mem"); 



	public JTreeFolder() throws HeadlessException {}
    
 

    private void addFolder(File driveOrDir, DefaultMutableTreeNode node, int level, boolean seeFile) {
        File[] fileList;

        fileList = driveOrDir.listFiles();

        try {
            for (int i = 0; i < fileList.length; i++) {
                if(seeFile==true||fileList[i].isFile()==false) {
                    NodeWithFile dir = new NodeWithFile(fileList[i].getName(), fileList[i]);
                    if (fileList[i].isDirectory() == true) {
                        addFolderTemp(fileList[i], dir);
                    }
                    node.add(dir);
                }
              
            }
        }
        catch (NullPointerException e) {
            return;
        }

    }

    //Permet l'ajout d'un node temporaire si node isDirectory
    public void addFolderTemp(File file, NodeWithFile node) {
        NodeWithFile temp = new NodeWithFile(file);
        node.add(temp);
    }
    
    public File getFile() {
        return ((NodeWithFile) tree.getLastSelectedPathComponent()).getFile();
    }
    
    
    
    public void addListenersToTree(final JTree tre)
    {
    	tre.removeAll();
    	tre.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
            	ev=evt;
                try {
                    TreePath path = evt.getPath();
                    if((path.getLastPathComponent().toString()).equals("Poste de travail")==true) {
                        File[] drive;
                        drive = File.listRoots();
                        //NodeWithFile[] driveNode = new NodeWithFile[drive.length];
                        for (int i = 0; i < drive.length; i++) {

                            NodeWithFile node = new NodeWithFile(drive[i], drive[i]);
                            addFolderTemp(drive[i], node);
                            racine.add(node);
                        }
                    }    
                    else {
                        NodeWithFile node = (NodeWithFile) path.getLastPathComponent(); //
                        node.removeAllChildren();
                        addFolder(node.getFile(), node, 1, seeFile);
                        ( (DefaultTreeModel) tree.getModel()).reload(node);
                    }
                }
                catch (Exception ex) {
                    //ex.printStackTrace();
                }
            }
        });

        tre.addTreeExpansionListener(new TreeExpansionListener() {
            public void treeExpanded(TreeExpansionEvent e) {

                try {
                    TreePath path = e.getPath();
                    if((path.getLastPathComponent().toString()).equals("Poste de travail")==true) {
                    	/*if(tre.isCollapsed(0))
                    	{*/
	                        File[] drive;
	                        drive = File.listRoots();
	                        for (int i = 0; i < drive.length; i++) {
	
	                            NodeWithFile node = new NodeWithFile(drive[i], drive[i]);
	                            addFolderTemp(drive[i], node);
	                            racine.add(node);
	
	                        }
                    	//}
                    }
                    else {
                    NodeWithFile node = (NodeWithFile) path.getLastPathComponent(); //
                    node.removeAllChildren();

                    addFolder(node.getFile(), node, 1, seeFile);

                    ( (DefaultTreeModel) tree.getModel()).reload(node);
                
                   }
                }
                catch (Exception ex) {
                    //System.out.println("erreur dans tree.expanded" + ex);
                }
            }

            public void treeCollapsed(TreeExpansionEvent e) {
                // lorsqu'un noeud est refermé
                //RIEN
                //voir ultérieurement si il ne faut pas faire removeAllChildren() !!!
            }
        });
    }
    

	
    /**
     * 
     */
	@Menu(libelle="JTreeFolder")
	@Override
	public JPanel getFrameDetail() {
		JPanel p = new JPanel();
		p.setLayout(new GridLayout(10, 3));
		p.add(new JLabel("Details       : JTreeFolder"));
		p.add(new JLabel("Version     : "+getVersion()));
		StringBuilder extension = new StringBuilder("");
		for(String e : getExtension())
			extension.append(" | "+e);
		p.add(new JLabel("Extension : "+extension));
		if(isDefault())
			p.add(new JLabel("par défaut  : Oui"));
		
		return p;
	}
	
	
	
	/**
	 * 
	 */
	@Override
	public JTree getTree() {
		
       tree = new JTree();
       racine = new NodeWithFile(new File("Poste de travail"));  //racine
       DefaultTreeModel model = new DefaultTreeModel(racine);
       tree.setCellRenderer(new Renderer());
       tree.setModel(model);
       addListenersToTree(tree);
        
		return tree;
	}

	

	/**
	 * 
	 */
	@Override
	public String[] getExtension() {
		
		return new String[]{"tree"};
	}
    
	/**
	 * 
	 */
	@Override
	public String getVersion() {

		return "1.0";
	}


	/**
	 * 
	 */
	@Override
	public TreeSelectionEvent getLastPath() {
		return ev;
	}



	/**
	 * 
	 */
	@Override
	public boolean isDefault() {
		
		return parDefaut;
	}
	
	
	/**
	 * 
	 */
	@Override
	public void setDefault(boolean bool) {
		parDefaut = bool;
		
	}
	/* public static void main(String[] arg)
    {
    	
        JFrame frame = new JFrame();
        JTreeFolder arbre = new JTreeFolder(true);
        
        frame.getContentPane().add(arbre, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
        frame.setBounds(0, 0, 800, 600);
        frame.setVisible(true);
    }*/



	/**
	 * 
	 */
	@Override
	public void saveTree() {

		try {
			
			FileOutputStream fos = new FileOutputStream(savingFile.getAbsolutePath());
			ObjectOutputStream oos= new ObjectOutputStream(fos);
			try {
				oos.writeObject(tree); 
				oos.flush();
			} finally {
				try {
					oos.close();
				} finally {
					fos.close();
				}
			}
		} catch(IOException ioe) {
			ioe.printStackTrace();
		}
	}



	/**
	 * 
	 */
	@Override
	public JTree loadTree() {
		if(savingFile.exists())
		{
			try {
				FileInputStream fis = new FileInputStream(savingFile.getAbsolutePath());
				ObjectInputStream ois= new ObjectInputStream(fis);
				try {	
					// désérialisation : lecture de l'objet depuis le flux d'entrée
					JTree arb = (JTree) ois.readObject();
					addListenersToTree(arb);
					return arb; 
				} finally {
					try {
						ois.close();
					} finally {
						fis.close();
					}
				}
			} catch(IOException ioe) {
				ioe.printStackTrace();
			} catch(ClassNotFoundException cnfe) {
				cnfe.printStackTrace();
			}
		}
		return null;
	}

}
